#ifndef AVPACKET_RINGBUFFER_H
#define AVPACKET_RINGBUFFER_H

#include <cstddef>
#include <stdexcept>

extern "C" {
#include <libavcodec/avcodec.h>
}

class RingBuffer {
public:
    explicit RingBuffer(size_t capacity) : capacity_(capacity + 1) {
        // 容量加1，以区分缓冲区满和空的状态（保留一个空槽位）
        if (capacity == 0) {
            throw std::invalid_argument("Capacity must be greater than zero");
        }
        buffer_ = new AVPacket*[capacity_];
        for (size_t i = 0; i < capacity_; ++i) {
            buffer_[i] = nullptr;
        }
    }

    ~RingBuffer() {
        // 释放所有剩余的 AVPacket
        while (!empty()) {
            AVPacket* pkt = pop();
            if (pkt) {
                av_packet_free(&pkt);
            }
        }
        delete[] buffer_;
    }

    // 禁用拷贝构造和赋值
    RingBuffer(const RingBuffer&) = delete;
    RingBuffer& operator=(const RingBuffer&) = delete;

    // 写入一个 AVPacket，成功返回true；如果缓冲区已满则返回false
    bool push(AVPacket* item) {
        if (full()) {
            return false;
        }
        buffer_[tail_] = item;
        tail_ = (tail_ + 1) % capacity_;
        return true;
    }

    // 读取一个 AVPacket，成功返回 AVPacket 指针；如果缓冲区为空则返回 nullptr
    AVPacket* pop() {
        if (empty()) {
            return nullptr;
        }
        AVPacket* value = buffer_[head_];
        head_ = (head_ + 1) % capacity_;
        return value;
    }

    // 查询缓冲区是否为空
    bool empty() const {
        return head_ == tail_;
    }

    // 查询缓冲区是否已满
    bool full() const {
        return ((tail_ + 1) % capacity_) == head_;
    }

    // 当前缓冲区中元素个数
    size_t size() const {
        if (tail_ >= head_) {
            return tail_ - head_;
        } else {
            return capacity_ - (head_ - tail_);
        }
    }

    // 缓冲区容量大小（最大可容纳元素数）
    size_t capacity() const {
        return capacity_ - 1;
    }

    // 清空缓冲区并释放所有 AVPacket
     void clear() {
         while (!empty()) {
             AVPacket* pkt = pop();
             if (pkt) {
                 av_packet_free(&pkt);
             }
         }
         head_ = 0;
         tail_ = 0;
     }

 private:
     AVPacket** buffer_ = nullptr;
     size_t capacity_;    // 实际分配的容量，比可用容量大1
     size_t head_ = 0;    // 读指针
     size_t tail_ = 0;    // 写指针
 };

 #endif // AVPACKET_RINGBUFFER_H
